#pragma once

/**
 * @brief 增加支持预处理的方法 
 * 有效避免SQL注入
 */

#include "ConnectionPool.hpp"
#include <jsoncpp/json/json.h>
#include <vector>

/**
 * @brief 封装常用CRUD操作
 * 数据库操作工具类
 */
class DBUtil
{
private:
	// 预处理语句包装类
	class Statement {
	private:
		MYSQL_STMT* stmt_ = nullptr;		// 预处理语句句柄

		// 递归绑定参数
		void bindParamsHelp(int);
		// 模板类 便于对应参数列表 更强的适配性
		template<typename T, typename... Args>
		void bindParamsHelp(int index, T&& val, Args&&... args); 

		// 不同类型的 bind 多种均可适配在args中
		// 可能是 (varchar 或者 int)
		void setBindValue(MYSQL_BIND& bind, int val);
		void setBindValue(MYSQL_BIND& bind, const string& val);

	public:
		Statement(MYSQL* conn, const string& sql);
		~Statement();

		// 要禁止拷贝构造和拷贝赋值
		Statement(const Statement&) = delete;
		Statement& operator=(const Statement&) = delete;

		/**
		 * @brief 多个参数进处理语句
		 * @param args 参数列表 可变参数 使用模板类可以更通配
		 */
		template<typename... Args>
		void bindParams(Args&&... args);

		/**
		 * @brief 执行预处理语句  
		 * 多种操作语句 封装在一个函数
		 * @return affected rows
		 */
		int execute();

		/**
		 * @brief 查询结果 --> Json对象对应的数据内容
		 * @return Json对象的数据
		 */
		Json::Value query();
	};
	
public:
	/**
	 * 执行SQL (affect rows)
	 * @param sql SQL查询语句
	 * @return 返回影响的行数 失败返回-1
	 */
	static int execute(const string& sql);

	/**
	 * 返回  JSON对象结果
	 * @param sql 查询语句
	 * @return 查询结果的JSON格式数据
	 */
	static Json::Value query(const string& sql);

	/**
     * 事务操作类
     * 用于封装数据库事务操作，确保数据的一致性和完整性。
     */
	class Transaction {
	public:
		/**
		 * 构造
		 * 事务实例，获取数据库连接
		 */
		Transaction();

		/**
		 * 析构
		 * 提交或者回滚事务，便于释放连接资源
		 */
		~Transaction();

		/**
		 * 提交事务
		 * 当前事务活跃就提交 返回bool值
		 */
		bool commit();

		/**
		 * 回滚
		 * 未提交 可以撤销已经做的更改
		 */
		void rollback();

		/**
		 * 
		 */
		bool execute(const std::string& sql);
		/**
		 * SQL 语句的执行
		 * 在事务中执行查询，返回查询结果的JSON格式数据。
		 * @param sql 查询的SQL语句
		 * @return 查询结果的JSON数据 json解析加校验
		 */
		Json::Value query(const string& sql);

	private:
		shared_ptr<MYSQL> conn_;		// 只能管理周期  事务内的数据库连接
		bool active_;					// 事务是否处于活跃  与连接池的状态结构体
	};
};

